import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text('gridView'),
          ),

          //SliverGridDelegateWithFixedCrossAxisCount
          /*
          crossAxisCount：横轴子元素的数量。此属性值确定后子元素在横轴的长度就确定了,
          即ViewPort横轴长度/crossAxisCount。
          mainAxisSpacing：主轴方向的间距。
          crossAxisSpacing：横轴方向子元素的间距。
          childAspectRatio：子元素在横轴长度和主轴长度的比例。
          由于crossAxisCount指定后子元素横轴长度就确定了，
          然后通过此参数值就可以确定子元素在主轴的长度。
          */
          // body: new GridView(
          //   gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          //       crossAxisCount: 3, //横轴三个子widget
          //       childAspectRatio: 1 // 宽高比为1，子widget
          //       ),
          //   children: <Widget>[
          //     Icon(Icons.ac_unit,color: Colors.red,),
          //     Icon(Icons.airport_shuttle),
          //     Icon(Icons.all_inclusive),
          //     Icon(Icons.beach_access),
          //     Icon(Icons.cake),
          //     Icon(Icons.free_breakfast)
          //   ],
          // ),
          //上面的示例代码等价于：
          // body: new GridView.count(
          //   crossAxisCount: 3,
          //   childAspectRatio: 2,
          //   children: <Widget>[
          //     Icon(
          //       Icons.ac_unit,
          //       color: Colors.red,
          //     ),
          //     Icon(Icons.airport_shuttle),
          //     Icon(Icons.all_inclusive),
          //     Icon(Icons.beach_access),
          //     Icon(Icons.cake),
          //     Icon(Icons.free_breakfast)
          //   ],
          // ),

          //SliverGridDelegateWithMaxCrossAxisExtent
          //该子类实现了一个横轴子元素为固定最大长度的layout算法
          //maxCrossAxisExtent 子元素在横轴上的最大长度
          //GridView.extent 可以快速创建
          // body: new GridView(
          //   padding: EdgeInsets.zero,
          //   gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
          //       maxCrossAxisExtent: 80, childAspectRatio: 2),
          //   children: <Widget>[
          //     Icon(Icons.ac_unit),
          //     Icon(Icons.airport_shuttle),
          //     Icon(Icons.all_inclusive),
          //     Icon(Icons.beach_access),
          //     Icon(Icons.cake),
          //     Icon(Icons.free_breakfast),
          //   ],
          // ),

          /*
          GridView.builder
          面我们介绍的GridView都需要一个Widget数组作为其子元素，这些方式都会提前将所有子widget都构建好
          只适用于子Widget数量比较少时，当子widget比较多时，
          我们可以通过GridView.builder来动态创建子Widget。
          */
          body: new InfiniteGridView(),
        ));
  }
}

class InfiniteGridView extends StatefulWidget {
  @override
  _InfiniteGridViewState createState() => new _InfiniteGridViewState();
}

class _InfiniteGridViewState extends State<InfiniteGridView> {
  List<IconData> _icons = []; //保存Icon数据

  @override
  void initState() {
    // 初始化数据
    _retrieveIcons();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4, //每行三列
            childAspectRatio: 1, //显示区域宽高相等
            ),
        itemCount: _icons.length,
        itemBuilder: (context, index) {
          //如果显示到最后一个并且Icon总数小于200时继续获取数据
          if (index == _icons.length - 1 && _icons.length < 200) {
            _retrieveIcons();
          }
          return Icon(_icons[index]);
        });
  }

  //模拟异步获取数据
  void _retrieveIcons() {
    Future.delayed(Duration(milliseconds: 200)).then((e) {
      setState(() {
        _icons.addAll([
          Icons.ac_unit,
          Icons.airport_shuttle,
          Icons.all_inclusive,
          Icons.beach_access,
          Icons.cake,
          Icons.free_breakfast
        ]);
      });
    });
  }
}
